package com.demo.springboot.generator;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.IFill;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.TemplateType;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.fill.Column;
import org.apache.ibatis.type.JdbcType;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author wangfengchen
 */
public class MyBatisPlusGenerator {

  private static final String PACKAGE_NAME = "com.demo.springboot";
  private static final String ENTITY_PACKAGE_NAME = "entity";
  private static final String MAPPER_PACKAGE_NAME = "mapper";
  private static final String SERVICE_PACKAGE_NAME = "service";
  private static final String MAPPER_XML_PATH = "/src/main/resources/mapper/";
  private static final String OUT_PATH = "/src/main/java";
  private static final String AUTHOR = "wangfengchen";
  /**
   * 逻辑删除配置
   */
  private static final String LOGIC_DELETE_COLUMN_NAME = "is_delete";
  /**
   * 属性自动填充配置
   */
  private static final List<IFill> FILL_COLUMN_LIST = Arrays.asList(new Column("create_time", FieldFill.INSERT),
      new Column("update_time", FieldFill.INSERT_UPDATE));
  /**
   * 要生成的数据库表名
   */
  private static final List<String> TABLE_NAME_LIST = Arrays.asList("user");
  private static final String URL = "jdbc:mysql://10.112.0.35:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai"
      + "&allowPublicKeyRetrieval=true";
  private static final String USERNAME = "dev_admin";
  private static final String PASSWORD = "sdifj20ha0dh";

  public static void main(String[] args) {
//        String projectPath = System.getProperty("user.dir");
    String str = ClassLoader.getSystemResource("").toString();
    String projectPath = str.substring(str.indexOf("/"), str.indexOf("/target"));
    System.out.println("项目所在磁盘位置：" + projectPath);

    FastAutoGenerator.create(URL, USERNAME, PASSWORD)
        // 全局配置
        .globalConfig(builder -> {
          // 获取生成的代码路径,这里没有写死，是运行时获取的，这样可以防止不同的开发人员来回修改生成路径的问题。
          builder.outputDir(projectPath + OUT_PATH).disableOpenDir()
//                            .enableSwagger() // 开启 swagger 模式，默认值false
              .dateType(DateType.ONLY_DATE)
              // 生成的类注释中的作者名称，为了统一表示，这里写死了
              .author(AUTHOR);
        })
        .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
          //注意如果数据库中设置tinyint长度为1，需要在上面数据库连接加上参数&tinyInt1isBit=false，这样就能转成INTEGER
          if (JdbcType.TINYINT == metaInfo.getJdbcType()) {
            return DbColumnType.INTEGER;
          }
          return typeRegistry.getColumnType(metaInfo);
        }))

        // 生成的代码包路径配置
        .packageConfig(builder -> {
          // 生成的代包公共路径
          builder.parent(PACKAGE_NAME);
          // 生成的实例类目录
          builder.entity(ENTITY_PACKAGE_NAME)
              // 生成的service目录
              .service(SERVICE_PACKAGE_NAME)
              // 生成的mapper目录
              .mapper(MAPPER_PACKAGE_NAME).pathInfo(Collections.singletonMap(OutputFile.xml, projectPath + MAPPER_XML_PATH));
        }).strategyConfig(builder -> {
          // 添加要生成的的数据库表
          builder.addInclude(TABLE_NAME_LIST)
              // 设置过滤表前缀
//                            .addTablePrefix("t_", "c_")
              // 启用大写模式
              .enableCapitalMode();
          // 配置实体类策略
          builder.entityBuilder()
              // 不生成serialVersionID
              .disableSerialVersionUID()
              // 表名驼峰命名
              .naming(NamingStrategy.underline_to_camel)
              // 字段名驼峰命名
              .columnNaming(NamingStrategy.underline_to_camel)
              // 使用lombok
              .enableLombok()
              // 开启链式模型
              .enableChainModel()
              // 标记实例类的主键生成方式，如果插入时没有指定，刚自动分配一个，默认是雪花算法
//                            .idType(IdType.ASSIGN_ID)
              .formatFileName("%sEntity").logicDeleteColumnName(LOGIC_DELETE_COLUMN_NAME).addTableFills(FILL_COLUMN_LIST)
              // 实例类每次生成的时候，覆盖旧的实体类
              .enableFileOverride();
          // 配置service策略
          builder.serviceBuilder().formatServiceFileName("%sService").formatServiceImplFileName("%sServiceImpl");
          // 配置mapper策略
          builder.mapperBuilder().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableBaseColumnList().enableBaseResultMap().fileOverride();
        }).templateConfig(builder -> {
          // 不生成Controller
          builder.disable(TemplateType.CONTROLLER);
        }).execute();
  }
}

